﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IntelligentDecisioning.SharePoint.Controls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
using IntelligentDecisioning.SharePoint.Helpers;
using System.Xml;
using IntelligentDecisioning.SharePoint.Logging;

namespace IntelligentDecisioning.SharePoint.Actions
{
    /// <summary>
    /// Provisions and instance of the builtin ListViewWebPart into a page
    /// </summary>
    public class ProvisionListViewAction: IPageAction
    {
        public String ListName { get; set; }
        public String ViewDisplayName { get; set; }
        public String Title { get; set; }
        public String WebPartZoneId { get; set; }
        public int Index { get; set; }
        public bool RemoveToolbar { get; set; }
        public bool ShowSummaryToolbar { get; set; }
        /// <summary>
        /// Set to true to include the "add new item link in the list view"
        /// </summary>
        public bool ShowAddNewItemLink { get; set; }

            
        #region IPageAction Members

        public bool HasTitle()
        {
            return (String.IsNullOrEmpty(Title)) ? false : true;
        }

        public void Provision(SPFile page, SPWeb currentWeb, SPSite currentSite, SPLimitedWebPartManager wpm, ILog installationLog)
        {
            try
            {

                installationLog.WriteToLog(String.Format("Attempting to provision list view webpart for view {0} on list {1}", ViewDisplayName, ListName));

                // Get the Target List
                IDListHelper listHelper = new IDListHelper(currentSite, currentWeb);
                SPList targetList = listHelper.GetList(ListName);

                // Get the View
                SPView targetView = targetList.Views[ViewDisplayName];

                // Create the listview webpart

                ListViewWebPart lvwp = new ListViewWebPart();
                lvwp.ListName = targetList.ID.ToString("B").ToUpper();
                lvwp.ViewGuid = targetView.ID.ToString("B").ToUpper();
                lvwp.ZoneID = WebPartZoneId;
                if (HasTitle())
                {
                    lvwp.Title = Title;
                }
                wpm.AddWebPart(lvwp, WebPartZoneId, Index);

                if (RemoveToolbar)
                {
                    installationLog.WriteToLog("Attempting to disable listview toolbar");
                    DisableToolbar(lvwp);
                }

                if (ShowSummaryToolbar)
                {
                    installationLog.WriteToLog("Attempting to show summary toolbar");
                    DisplaySummaryToolbar(lvwp);
                }

                wpm.SaveChanges(lvwp);
            }
            catch (Exception e)
            {
                installationLog.WriteToLog(String.Format("An exception occurred while attempting to provision list view webpart for view {0} on list {1} {2}", ViewDisplayName, ListName, e.ToString()));
            }
        }

        private void DisplayAddNewItemLink(XmlNode tBarNode, SPView spView)
        {
           //? might only work if the summary toolbar is displayed

            // Add the new item link
            string NewItemString = string.Empty;


            // Create a position attribute
            XmlAttribute pos = tBarNode.OwnerDocument.CreateAttribute("Position");
            pos.Value = pos.Value = "After";
            tBarNode.Attributes.Append(pos);

            switch (spView.ParentList.BaseTemplate)
            {
                case SPListTemplateType.DiscussionBoard:
                    NewItemString = "discussion";
                    break;

                case SPListTemplateType.Links:
                    NewItemString = "link";
                    break;

                case SPListTemplateType.Tasks:
                    NewItemString = "task";
                    break;

                case SPListTemplateType.GenericList:
                    NewItemString = "item";
                    break;

                case SPListTemplateType.DocumentLibrary:
                    NewItemString = "document";
                    break;
            }

            tBarNode.InnerXml = @"<IfHasRights>" +
                                    "<RightsChoices>" +
                                        "<RightsGroup PermAddListItems='required' />" +
                                    "</RightsChoices>" +
                                  "<Then>" +
                                        "<HTML>" +
                                            "<![CDATA[ <table width=100% cellpadding=0 cellspacing=0 border=0 >" +
                                                "<tr> <td colspan='2' class='ms-partline'>" +
                                                    "<IMG src='/_layouts/images/blank.gif' width=1 height=1 alt=''>" +
                                                 "</td> </tr>" +
                                                "<tr> <td class='ms-addnew' style='padding-bottom: 3px'>" +
                                                "<img src='/_layouts/images/rect.gif' alt=''>&nbsp;" +
                                                "<a class='ms-addnew' ID='idAddNewItem' href='']]>" +
                                            "</HTML>" +
                                               "<URL Cmd='New' />" +
                                            "<HTML><![CDATA[' ONCLICK='javascript:NewItem(']]></HTML>" +
                                                "<URL Cmd='New' /><HTML>" +
                                                "<![CDATA[', true);javascript:return false;' target='_self'>]]></HTML>" +
                                                "<HTML>Add a new  + NewItemString</HTML>" +
                                                "<HTML><![CDATA[</a> </td> </tr> <tr><td>" +
                                                "<IMG src='/_layouts/images/blank.gif' width=1 height=5 alt=''>" +
                                                "</td></tr> </table>]]></HTML>" +
                                      "</Then></IfHasRights>";

        }
        /// <summary>
        /// http://tippu.blog.co.in/2008/10/08/how-to-set-a-listviewwebparts-toolbar-type-as-summary-web-part/
        /// </summary>
        /// <param name="lvwp"></param>
        private void DisplaySummaryToolbar(ListViewWebPart lvwp)
        {

            //  Extract view 

            System.Reflection.PropertyInfo ViewProp = lvwp.GetType().GetProperty("View",
             System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            SPView spView = ViewProp.GetValue(lvwp, null) as SPView;

            string txt = spView.SchemaXml;

            System.Reflection.PropertyInfo NodeProp = spView.GetType().GetProperty("Node",
             System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            XmlNode node = NodeProp.GetValue(spView, null) as XmlNode;

            XmlNode tBarNode = node.SelectSingleNode("Toolbar");


            if (tBarNode != null)
            {
                XmlAttribute typeNode = tBarNode.Attributes["Type"];
                tBarNode.RemoveAll();
                tBarNode.Attributes.Append(typeNode);
                typeNode.Value = "Freeform";
            }


            if (ShowAddNewItemLink)
            {
                DisplayAddNewItemLink(tBarNode, spView);
            }

            spView.Update();
        }


        /// <summary>
        /// http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/96aac2dd-29fc-4e63-8730-9d1adc01b826/
        /// </summary>
        /// <param name="lv"></param>
        private void DisableToolbar(ListViewWebPart lv)
        {

            //  Extract view 

            System.Reflection.PropertyInfo ViewProp = lv.GetType().GetProperty("View",
             System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            SPView spView = ViewProp.GetValue(lv, null) as SPView;
            string txt = spView.SchemaXml;

            System.Reflection.PropertyInfo NodeProp = spView.GetType().GetProperty("Node",
              System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            XmlNode node = NodeProp.GetValue(spView, null) as XmlNode;

            XmlNode tBarNode = node.SelectSingleNode("Toolbar");


            if (tBarNode != null)
            {

                XmlAttribute typeNode = tBarNode.Attributes["Type"];

                // make the contents empty so we realy remove the toolbar .....

                // otherwise you might get a different type of toolbar popup when we have a 
                // Migrated site from 2.0

                tBarNode.RemoveAll();

                // re-add the type attribute

                tBarNode.Attributes.Append(typeNode);

                // finally set the toolbar to not show....

                typeNode.Value = "None";

            }

            if (ShowAddNewItemLink)
            {
                DisplayAddNewItemLink(tBarNode, spView);
            }

            //This forces a refresh of the views internal xml or the node's child nodes are not populated 

            spView.Update();
        }

        #endregion
    }
}
